using System;
using System.Runtime.InteropServices;

namespace Toenda.Foundation.Windows.Forms {
	/// <summary>
	/// SystemImageList
	/// </summary>
	public class SystemImageList {
		private static IntPtr _pImgHandle = IntPtr.Zero;
		private static Boolean _bImgInit = false;

		private const UInt32 TVSIL_NORMAL = 0;
		private const UInt32 TVM_SETIMAGELIST = 4361;

		// ---------------------------------------------------
		// CONSTRUCTORS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// INTERFACE IMPLEMENTATIONS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PROPERTIES
		// ---------------------------------------------------

		// ---------------------------------------------------
		// EVENTS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PRIVATE MEMBERS
		// ---------------------------------------------------

		/// <summary>
		/// Retrieves the handle of the system image list.
		/// </summary>
		private static void InitImageList() {
			// Only initialize once.
			if(_bImgInit) {
				throw new Exception("The system image list handle has already been retrieved.");
			}

			// Retrieve the info for a fake file so we can get the image list handle.
			ShellAPI.SHFILEINFO shInfo = new ShellAPI.SHFILEINFO();

			ShellAPI.SHGFI dwAttribs =
				ShellAPI.SHGFI.SHGFI_USEFILEATTRIBUTES |
				ShellAPI.SHGFI.SHGFI_SMALLICON |
				ShellAPI.SHGFI.SHGFI_SYSICONINDEX;

			_pImgHandle = ShellAPI.SHGetFileInfo(
				".txt", 
				ShellAPI.FILE_ATTRIBUTE_NORMAL, 
				out shInfo, 
				(uint)Marshal.SizeOf(shInfo), 
				dwAttribs
			);

			// Make sure we got the handle.
			if(_pImgHandle.Equals(IntPtr.Zero)) {
				throw new Exception("Unable to retrieve system image list handle.");
			}

			// Only allow one initialization.
			_bImgInit = true;
		}

		// ---------------------------------------------------
		// PROTECTED MEMBERS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PUBLIC MEMBERS
		// ---------------------------------------------------

		/// <summary>
		/// Sets the image list for the TreeView to the system image list.
		/// </summary>
		/// <param name="tvwHandle">The window handle of the TreeView control</param>
		public static void SetTVImageList(IntPtr tvwHandle) {
			InitImageList();

			Int32 hRes = ShellAPI.SendMessage(
				tvwHandle, 
				TVM_SETIMAGELIST, 
				TVSIL_NORMAL, 
				_pImgHandle
			);

			if(hRes != 0) {
				Marshal.ThrowExceptionForHR(hRes);
			}
		}
	}
}
